package utils

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"
	"unicode"
)

// tpl 使用增加执行目录进入
func JoinFile(path string) string {
	exePath := filepath.Dir(os.Args[0])
	return filepath.Join(exePath, path)
}

// 转换绝对路径
func GetAbsPath(path string) string {
	nowPath, err := os.Getwd()
	if err != nil {
		fmt.Println("获取当前路径失败,", err.Error())
	}
	// 判断绝对路径
	if filepath.IsAbs(path) {
		return path
	}
	return filepath.Join(nowPath, path)
}

// 查看目录或者文件是否存在
func FileOrDirExists(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		return os.IsExist(err)
	}
	return true
}

// 判断所给路径是否为文件夹 文件须存在
func IsDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

// 判断所给路径是否为文件 文件须存在
func IsFile(path string) bool {
	return !IsDir(path)
}

// 创建目录
func MakeDirAll(path string) error {
	if FileOrDirExists(path) {
		return nil
	}
	return os.MkdirAll(path, os.ModePerm)
}

// 创建文件，如果存在不创建
func TourchFile(goFilePath, goFileTpl, tplName string, tplParams any) error {
	// 生成的目标文件
	goFileName := goFilePath
	if FileOrDirExists(goFileName) {
		return nil
	}
	// 读模版文件
	tplContent, err := os.ReadFile(JoinFile(goFileTpl))
	if err != nil {
		return err
	}
	// 创建输出文件
	outputFile, err := os.Create(goFileName)
	if err != nil {
		return err
	}
	defer outputFile.Close()
	// 使用 text/template 包创建模板
	tpl := template.Must(template.New(tplName).Parse(string(tplContent)))
	// 渲染模板并写入到输出文件
	err = tpl.Execute(outputFile, tplParams)
	if err != nil {
		return err
	}
	return nil
}

// 蛇形转大驼峰
func SnakeToPascal(s string) string {
	// 使用 strings.Split 按 "_" 分割字符串
	parts := strings.Split(s, "_")
	for i := range parts {
		// 将每个部分的首字母大写
		if len(parts[i]) > 0 {
			parts[i] = string(unicode.ToUpper(rune(parts[i][0]))) + parts[i][1:]
		}
	}
	// 拼接所有部分
	return strings.Join(parts, "")
}

// IsValidVariableName 检查字符串是否符合 Go 变量命名规范，且不能以下划线开头
func IsValidVariableName(name string) bool {
	// 检查长度
	if len(name) == 0 {
		return false
	}

	// 检查首字符
	firstChar := rune(name[0])
	if !unicode.IsLetter(firstChar) {
		return false
	}

	// 检查后续字符
	for _, char := range name {
		if !unicode.IsLetter(char) && !unicode.IsDigit(char) && char != '_' {
			return false
		}
	}

	// 检查是否为关键字
	keywords := map[string]bool{
		"break": true, "default": true, "func": true, "interface": true, "select": true,
		"case": true, "defer": true, "go": true, "map": true, "struct": true,
		"chan": true, "else": true, "goto": true, "package": true, "switch": true,
		"const": true, "fallthrough": true, "if": true, "range": true, "type": true,
		"continue": true, "for": true, "import": true, "return": true, "var": true,
	}
	if _, ok := keywords[name]; ok {
		return false
	}

	return true
}
